package com.unitechs.trap.excel.webapi.service.impl.udp;

import com.alibaba.fastjson.JSONObject;
import com.unitechs.trap.excel.service.ILogTestService;
import com.unitechs.trap.excel.webapi.utils.FileUtil;
import com.unitechs.trap.excel.webapi.utils.HttpPostRequestUtils;
import com.unitechs.trap.excel.webapi.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class LogTestServiceImpl implements ILogTestService {


    /**
     * 将日志转换成两种Json格式
     * 1、用于界面测试的Json
     * 2、用于接口测试的Json
     *
     * @param url
     * @param devicesIp
     */
    @Override
    public void changeLogToJson(String url, String devicesIp) {
        File file = new File(url);
        List<File> nonDirectoryFiles = FileUtil.getNonDirectoryFiles(file);
        for (File f : nonDirectoryFiles) {
            if (f.getName().endsWith(".xls")) {
                try {
                    //创建工作簿对象
                    HSSFWorkbook xssfWorkbook = new HSSFWorkbook(new FileInputStream(f.getPath()));
                    //读取第1个工作表
                    HSSFSheet sheet = xssfWorkbook.getSheetAt(0);
                    //获取最后一行的num，即总行数。此处从0开始
                    int maxRow = sheet.getLastRowNum();
                    for (int row = 0; row <= maxRow; row++) {
                        if (isNull(sheet.getRow(row).getCell(0))) {
                            continue;
                        }
                        if (isNull(sheet.getRow(row).getCell(1))) {
                            continue;
                        }
                        JSONObject trapJson = JsonUtil.getTrapJson(sheet.getRow(row).getCell(0).toString());
                        trapJson.put("trapOid", sheet.getRow(row).getCell(1).toString());
                        trapJson.put("ResIP", devicesIp);
                        HSSFRow hssfRow = sheet.getRow(row);
                        if (hssfRow == null) {
                            hssfRow = sheet.createRow(row);
                        }

                        // 获取现有的单元格对象，如果不存在则创建新单元格
                        HSSFCell hssfCell = hssfRow.getCell(2);
                        if (hssfCell == null) {
                            hssfCell = hssfRow.createCell(2);
                        }
                        //写界面Json
                        hssfCell.setCellValue(trapJson.toString().replace(",", ",\n").replace(",\n ", ", "));

                        hssfCell = hssfRow.getCell(3);
                        if (hssfCell == null) {
                            hssfCell = hssfRow.createCell(3);
                        }
                        //写接口Json
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("trapMessage", trapJson);
                        hssfCell.setCellValue(jsonObject.toString());

                    }
                    FileOutputStream fos = new FileOutputStream(f);
                    xssfWorkbook.write(fos);
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 向接口发送请求
     * @param fileUrl
     * @param interfaceUrl
     * @param token
     */
    @Override
    public void sendRequestToInterFace(String fileUrl, String interfaceUrl, String token) {
        File file = new File(fileUrl);
        List<File> nonDirectoryFiles = FileUtil.getNonDirectoryFiles(file);
        for (File f : nonDirectoryFiles) {
            if (f.getName().endsWith(".xls")) {
                try {
                    //创建工作簿对象
                    HSSFWorkbook xssfWorkbook = new HSSFWorkbook(new FileInputStream(f.getPath()));
                    //读取第1个工作表
                    HSSFSheet sheet = xssfWorkbook.getSheetAt(0);
                    //获取最后一行的num，即总行数。此处从0开始
                    int maxRow = sheet.getLastRowNum();
                    for (int row = 0; row <= maxRow; row++) {
                        if (isNull(sheet.getRow(row).getCell(3))) {
                            continue;
                        }
                        String response = HttpPostRequestUtils.trapHttpPostRequest(interfaceUrl, token, sheet.getRow(row).getCell(3).toString());
                        response=responseDataToExcel(response);
                        HSSFRow hssfRow = sheet.getRow(row);
                        if (hssfRow == null) {
                            hssfRow = sheet.createRow(row);
                        }

                        // 获取现有的单元格对象，如果不存在则创建新单元格
                        HSSFCell hssfCell = hssfRow.getCell(4);
                        if (hssfCell == null) {
                            hssfCell = hssfRow.createCell(4);
                        }
                        hssfCell.setCellValue(response);

                    }
                    FileOutputStream fos = new FileOutputStream(f);
                    xssfWorkbook.write(fos);
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    /**
     * 从日志中读取文件到Excel
     *
     * @param url
     */
    @Override
    public void logFileToExcel(String url) {
        File file = new File(url);
        List<String> list = new ArrayList<>();
        List<File> nonDirectoryFiles = FileUtil.getNonDirectoryFiles(file);
        for (File f : nonDirectoryFiles) {
            List<String> logs = FileUtil.readLogFromFile(f);
            list.addAll(logs);
        }
        list = removeDuplicate(list);
        log.info("去重后集合长度{}", list.size());
        FileUtil.outLogAndOidToExcelCell(list);
    }

    /**
     * 根据OID去重
     *
     * @param list
     * @return
     */
    private List<String> removeDuplicate(List<String> list) {
        Pattern pattern = Pattern.compile(".*OID:\\s*(?<value>[^\\s]+).*");
        Set<String> uniqueOids = new HashSet<>();
        List<String> filteredList = new ArrayList<>();
        for (String s : list) {
            Matcher matcher = pattern.matcher(s);
            if (matcher.find()) {
                String oid = matcher.group("value");
                if (uniqueOids.add(oid)) {
                    filteredList.add(s);
                    log.info("log{}", oid);
                }
            }
        }
        return filteredList;
    }


    /**
     * 解析接口返回的数据
     * @param response
     * @return
     */
    private String responseDataToExcel(String response) {
        response=response.replace("{","\n{").replace(",",",\n");
        response=response.toLowerCase();
        log.info("response修改后{}",response);
        String regexAlarm = "\\{\"attributecode\":\"(?<attributecode>.*?)\",\n" +
                "\"attributeescode\":\"(.*?)\",\n" +
                "\"attributename\":\"(.*?)\",\n" +
                "\"attributevalue\":\"(?<attributevalue>.*?)\",\n" +
                "\"displayorder\":\"(.*?)\"},";

        String alarmstatus = "";
        String alarmclass = "";
        String alarmclassname = "";
        String alarmtypeid = "";
        String alarmtype = "";
        String severity = "";
        String alarmlevelname = "";
        String handlerulename = "";


        Pattern pattern = Pattern.compile(regexAlarm);
        Matcher matcher = pattern.matcher(response);

        while (matcher.find()) {
            switch (matcher.group("attributecode")) {
                case "alarmstatus":
                    alarmstatus = matcher.group("attributevalue");
                    break;
                case "alarmclass":
                    alarmclass = matcher.group("attributevalue");
                    break;
                case "alarmclassname":
                    alarmclassname = matcher.group("attributevalue");
                    break;
                case "alarmtypeid":
                    alarmtypeid = matcher.group("attributevalue");
                    break;
                case "alarmtype":
                    alarmtype = matcher.group("attributevalue");
                    break;
                case "severity":
                    severity = matcher.group("attributevalue");
                    break;
                case "alarmlevelname":
                    alarmlevelname = matcher.group("attributevalue");
                    break;
                case "handlerulename":
                    handlerulename = matcher.group("attributevalue");
                    break;
            }

        }
        if (!alarmstatus.equals("0") && (alarmstatus.equals("")
                || alarmclass.equals("")
                || alarmclassname.equals("")
                || alarmtypeid.equals("")
                || alarmtype.equals("")
                || severity.equals("")
                || alarmlevelname.equals(""))
        ) {
            response = "alarmstatus(告警状态 ):" + alarmstatus +
                    ";\nalarmclass(告警类别编码):" + alarmclass +
                    ";\nalarmclassname(告警类别名称):" + alarmclassname +
                    ";\nalarmtypeid(告警类型编码):" + alarmtypeid +
                    ";\nalarmtype(告警类型名称):" + alarmtype +
                    ";\nseverity(告警级别):" + severity +
                    ";\nalarmlevelname(告警级别名称):" + alarmlevelname +
                    ";\nhandlerulename(告警处理规则):" + handlerulename +
                    ";\n匹配结果:失败";
        } else {
            response = "alarmstatus(告警状态 ):" + alarmstatus +
                    ";\nalarmclass(告警类别编码):" + alarmclass +
                    ";\nalarmclassname(告警类别名称):" + alarmclassname +
                    ";\nalarmtypeid(告警类型编码):" + alarmtypeid +
                    ";\nalarmtype(告警类型名称):" + alarmtype +
                    ";\nseverity(告警级别):" + severity +
                    ";\nalarmlevelname(告警级别名称):" + alarmlevelname +
                    ";\nhandlerulename(告警处理规则):" + handlerulename +
                    ";\n匹配结果:成功";
        }
        return response;
    }


    private boolean isNull(Cell cell) {
        if (cell == null) {
            return true;
        } else {
            return false;
        }
    }

}
